package com.parent.framework.elasticsearch.utils;

import cn.hutool.core.collection.CollUtil;
import cn.hutool.core.util.ObjectUtil;
import org.springframework.data.domain.PageRequest;
import org.springframework.data.domain.Pageable;
import org.springframework.data.domain.Sort;

import java.lang.reflect.Field;
import java.util.*;


/**
 * @Author yan
 * @Date 2023/9/27 0027 14:54
 * @Description 不建议使用
 */

public class ElasticsearchUtils {

    /**
     * @param pageNumber
     * @param pageSize
     * @param sort       Sort.Order weight = new Sort.Order(Sort.Direction.ASC, "weight");
     * @return
     */
    public static Pageable getPage(Integer pageNumber, Integer pageSize, Sort sort) {
        int pageNumberIntValue = pageNumber.intValue();
        int pageNum = pageNumberIntValue == 0 ?
                pageNumberIntValue : (pageNumberIntValue < 0) ? 0 : pageNumberIntValue - 1;
        int size = pageSize.intValue();

        Pageable pageable = ObjectUtil.isEmpty(sort) ?
                PageRequest.of(pageNum, size) : PageRequest.of(pageNum, size, sort);
        return pageable;
    }

    /**
     * 字符串中获取另一字符串的所有索引位置
     *
     * @param value
     * @param key
     * @return
     */
    public static List<Integer> getStringKeyIndexs(String value, String key) {
        List<Integer> indexs = new ArrayList<>();
        int frontLength = 0;//定义该变量用于记录匹配"love"的元素前面的长度
        String tempValues = value;
        while (tempValues.contains(key)) {//只要该str字符串中有匹配"love"的元素，才进行以下操作
            int index = tempValues.indexOf(key);//定义该变量用于记录匹配"love"的元素在当前字符串的位置
            //匹配"love"的元素位置等于frontLength加上index；加1为了从1开始计数，更加直观：
            //System.out.println(String.format("str[%d] = love", index + frontLength + 1));
            indexs.add(index + frontLength);
            frontLength += (index + key.length());
            tempValues = tempValues.substring(index + key.length());//将字符串中匹配"love"元素的前面部分及其本身截取，留下后面的部分
        }
        return indexs;
    }

    /**
     * 替换
     *
     * @param indexs --索引位置 集合
     * @param values
     * @param key 
     * @param preTag
     * @param postTag
     * @return
     */
    public static String replaceAllList(List<Integer> indexs, String values, String key, String preTag, String postTag) {

        preTag =ObjectUtil.isEmpty(preTag)? "":preTag;
        postTag =ObjectUtil.isEmpty(postTag)? "":postTag;

        StringBuilder valueBuilder = new StringBuilder(values);
        int length = key.length();
        Integer addIndex = 0;
        String reKey = new StringBuilder(preTag).append(key).append(postTag).toString();

        if (CollUtil.isNotEmpty(indexs)) {
            for (int i = 0; i < indexs.size(); i++) {
                Integer index = indexs.get(i);
                if (i!=0){
                    addIndex = addIndex + preTag.length() + postTag.length();
                    index = index + addIndex;
                }
                valueBuilder.replace(index, index + length, reKey);
            }
        }
        return valueBuilder.toString();
    }

    /**
     * 设置高亮
     *
     * @param content
     * @param highlightFields
     * @throws NoSuchFieldException
     * @throws IllegalAccessException
     */
    public static void setHighlight(Object content, Map<String, List<String>> highlightFields) throws NoSuchFieldException, IllegalAccessException {
        Class<?> aClass = content.getClass();
        Field[] fields = aClass.getDeclaredFields();
        for (Field field : fields) {
            // 允许访问私有属性
            field.setAccessible(true);
            String name = field.getName();
            List<String> strings = highlightFields.get(name);
            if (CollUtil.isNotEmpty(strings)) {
                Field fieldNow = aClass.getDeclaredField(name);
                fieldNow.setAccessible(true);
                field.set(content, strings.get(0));//设置属性值
            }
        }
    }

    /**
     * 设置高亮
     *
     * @param content
     * @param highlightFields 高亮字段
     * @param keys            需要高亮的字
     * @param preTag          高亮前缀
     * @param postTag         高亮后缀
     * @throws NoSuchFieldException
     * @throws IllegalAccessException
     */
    public static void appointSetHighlight(Object content, List<String> highlightFields, List<String> keys, String preTag, String postTag) throws NoSuchFieldException, IllegalAccessException {
        preTag = ObjectUtil.isEmpty(preTag) ? "" : preTag;
        postTag = ObjectUtil.isEmpty(postTag) ? "" : postTag;

        Class<?> aClass = content.getClass();
        Field[] fields = aClass.getDeclaredFields();
        for (Field field : fields) {
            // 允许访问私有属性
            field.setAccessible(true);
            String name = field.getName();
            if (CollUtil.isNotEmpty(highlightFields) && highlightFields.contains(name)) {
                Field fieldNow = aClass.getDeclaredField(name);
                fieldNow.setAccessible(true);
                String value = "";

                if (ObjectUtil.isNotEmpty(content)) {
                    value = (String) fieldNow.get(content);
                    StringBuilder valueBuilder = new StringBuilder(value);
                    if (CollUtil.isNotEmpty(keys)) {
                        for (String key : keys) {
                            if (value.contains(key)) {
                                List<Integer> indexs = getStringKeyIndexs(value, key);

                                if (CollUtil.isNotEmpty(indexs) &&
                                        ObjectUtil.isNotEmpty(preTag) &&
                                        ObjectUtil.isNotEmpty(postTag) &&
                                        ObjectUtil.isNotEmpty(key)) {
                                    String reAll = replaceAllList(indexs, value, key, preTag, postTag);
                                    valueBuilder = new StringBuilder(reAll);
                                }

                            }
                        }
                    }

                    value = valueBuilder.toString();
                    field.set(content, value);//设置属性值
                }
            }
        }
    }

    /**
     * 设置高亮
     *
     * @param content
     * @param highlightFields 高亮字段
     * @param highlightMap    高亮前的内容存储映射(如高亮字段为 a ->映射b,b就是没有高亮前的字段)
     * @param keys            需要高亮的字
     * @param preTag          高亮前缀
     * @param postTag         高亮后缀
     * @throws NoSuchFieldException
     * @throws IllegalAccessException
     */
    public static void appointSetHighlight(Object content, List<String> highlightFields, Map<String, String> highlightMap, List<String> keys, String preTag, String postTag) throws NoSuchFieldException, IllegalAccessException {
        Map<String, Object> map = new LinkedHashMap<>();
        Class<?> aClass = content.getClass();
        Field[] fields = aClass.getDeclaredFields();
        for (Field field : fields) {
            // 允许访问私有属性
            field.setAccessible(true);
            String name = field.getName();
            String value = "";
            if (CollUtil.isNotEmpty(highlightFields) && highlightFields.contains(name)) {
                Field fieldNow = aClass.getDeclaredField(name);
                fieldNow.setAccessible(true);

                if (ObjectUtil.isNotEmpty(content)) {
                    value = (String) fieldNow.get(content);
                    StringBuilder valueBuilder = new StringBuilder(value);
                    map.put(name,value);
                    if (CollUtil.isNotEmpty(keys)) {
                        for (String key : keys) {

                            if (value.contains(key)) {
                                List<Integer> indexs = getStringKeyIndexs(value, key);

                                if (CollUtil.isNotEmpty(indexs) &&
                                        ObjectUtil.isNotEmpty(preTag) &&
                                        ObjectUtil.isNotEmpty(postTag) &&
                                        ObjectUtil.isNotEmpty(key)) {
                                    String reAll = replaceAllList(indexs, value, key, preTag, postTag);
                                    valueBuilder = new StringBuilder(reAll);
                                }

                            }
                            value = valueBuilder.toString();
//                            if (value.contains(key)) {
//                                preTag = ObjectUtil.isEmpty(preTag) ? "" : preTag;
//                                postTag = ObjectUtil.isEmpty(postTag) ? "" : postTag;
//                                String reKey = new StringBuilder(preTag).append(key).append(postTag).toString();
//                                value = value.replaceAll(key, reKey);
//                            }
                        }
                    }
                    //高亮替换
                    field.set(content, value);//设置属性值
                }
            }
        }

        if (highlightMap != null) {
            Map<String, Object> hashMap = new LinkedHashMap<>();
            Set<Map.Entry<String, String>> entries = highlightMap.entrySet();
            entries.stream().forEach(one->{
                String name = one.getKey();
                Object o = map.get(name);
                if (ObjectUtil.isNotEmpty(o)){
                    String oldName = one.getValue();
                    hashMap.put(oldName,o);
                }
            });
            for (Field field : fields) {
                // 允许访问私有属性
                field.setAccessible(true);
                String name = field.getName();
                Object o = hashMap.get(name);
                if (ObjectUtil.isNotEmpty(o)) {
                    //原字段赋值
                    Field fieldNowOld = aClass.getDeclaredField(name);
                    fieldNowOld.setAccessible(true);
                    field.set(content, o);//设置属性值
                }
            }
        }
    }
}
